import type { WindowContext } from "@/core/window/window-context"
import * as _ from "lodash"

export class WindowActiveProcessor {
  private activeWindowId?: string

  private zIndex: Map<string, number> = new Map<string, number>()

  private windowContext: WindowContext

  constructor(windowContext: WindowContext) {
    this.windowContext = windowContext
  }

  getActiveWindowId() {
    return this.activeWindowId
  }

  active(windowId?: string) {
    if (this.activeWindowId === windowId) {
      return
    }
    const doActive = (windowId: string) => {
      //将当前活跃窗口设置到顶层
      this.activeWindowId = windowId
      this.zIndex.set(windowId, this.findMaxZIndex() + 1)
      const window = this.windowContext.windows.get(windowId)
      if (window && window.getStatus() === "minimize") {
        window.switchMinimize()
      }
      //活跃当前应用
      this.windowContext.application.applicationContext.activeProcessor.active(
        this.windowContext.application.id
      )
    }
    if (windowId) {
      doActive(windowId)
    } else {
      const findMaxZIndexWindowId = this.findMaxZIndexWindowId()
      if (findMaxZIndexWindowId) {
        doActive(findMaxZIndexWindowId)
      }
    }
  }

  inactive() {
    if (!this.activeWindowId) {
      return
    }
    this.activeWindowId = undefined
  }

  getZIndex(windowId: string) {
    return this.zIndex.get(windowId) || 0
  }

  private findMaxZIndex() {
    return _.max([...this.zIndex.values()]) || 0
  }

  private findMaxZIndexWindowId() {
    let maxZIndexWindowId
    let maxZIndex = -1
    for (const [key, value] of this.zIndex) {
      if (value > maxZIndex) {
        maxZIndexWindowId = key
        maxZIndex = value
      }
    }
    return maxZIndexWindowId
  }

  fromState(obj: any): void {
    if (!obj) {
      return
    }
    _.forEach(obj.zIndex, (key: string, value: number) => {
      this.zIndex.set(key, value)
    })
    const sorted = _.sortBy(_.toPairs(this.zIndex), ([, value]) => value)
    for (let i = 0; i < sorted.length; i++) {
      this.zIndex.set(sorted[i][0], i)
    }
    this.active(obj.activeWindowId)
  }

  toState(): any {
    const obj: any = {}
    obj.activeWindowId = this.activeWindowId
    obj.zIndex = _.fromPairs(Array.from(this.zIndex.entries()))
    return obj
  }
}
